import click
import os
import shutil
import time

from .task_generator import TaskGenerator
from .backends.local_lkp import LocalLkpBackend
from .analysis_engine import AnalysisEngine
from .report_generator import ReportGenerator
from .backends.scheduler_backend import SchedulerBackend

@click.group()
def cli():
    """性能对比分析工具 (LKP本地执行优先版)"""
    pass

@cli.command()
@click.option('--base-yaml', required=True, type=click.Path(exists=True, dir_okay=False), help='基础YAML配置文件路径。')
@click.option('--vary', required=True, help='要变更的维度，例如 "ss.linux.commit"。')
@click.option('--values', required=True, help='维度的两个值，用逗号分隔，例如 "commitA,commitB"。')
@click.option('--output-dir', default='./perf_results', help='结果和报告的输出目录。')
@click.option('--backend', default='local', type=click.Choice(['local', 'scheduler']), show_default=True, help='执行后端，可选 local 或 scheduler。')
@click.option('--runs', default=1, show_default=True, help='每个配置重复运行次数')
def compare(base_yaml, vary, values, output_dir, backend, runs):
    """
    “一条龙”服务：生成配置 -> 本地运行LKP -> 对比结果 -> 生成报告。
    """
    click.secho(f"🚀 开始端到端性能对比任务...", fg='cyan')
    
    # 准备输出目录
    os.makedirs(output_dir, exist_ok=True)
    
    # 1. 解析输入值
    try:
        value_a, value_b = values.split(',', 1)
        value_a, value_b = value_a.strip(), value_b.strip()
    except ValueError:
        raise click.UsageError("`--values` 参数必须是两个用逗号分隔的值。")

    try:
        # 2. 生成任务配置
        click.echo("  -> 步骤1/4: 生成任务配置文件...")
        task_gen = TaskGenerator(base_yaml_path=base_yaml, work_dir=output_dir)
        job_a_config_path, job_b_config_path = task_gen.generate(vary, value_a, value_b)
        click.echo(f"     成功生成: {os.path.basename(job_a_config_path)}, {os.path.basename(job_b_config_path)}")

        # 3. 执行任务
        click.echo("  -> 步骤2/4: 执行LKP任务 (可能需要sudo权限)...")
        if backend == 'local':
            executor = LocalLkpBackend()
        elif backend == 'scheduler':
            try:
                from .backends.scheduler_backend import SchedulerBackend
                executor = SchedulerBackend()
            except ImportError:
                raise click.UsageError("SchedulerBackend 未实现或导入失败。")
        else:
            raise click.UsageError(f"未知 backend: {backend}")
            
        job_ids_a = executor.run(job_a_config_path, runs)
        time.sleep(5)
        job_ids_b = executor.run(job_b_config_path, runs)
        all_job_ids = job_ids_a + job_ids_b
        min_successful = max(3, runs)
        if executor.wait_jobs(all_job_ids, min_successful=min_successful):
            click.echo(f"     所有任务完成")
        else:
            raise click.UsageError(f"任务执行失败")

        # 4. 分析结果
        click.echo("  -> 步骤3/4: 对比分析结果...")
        analyzer = AnalysisEngine()
        comparison_data = analyzer.analyze_compass_results(job_ids_a, job_ids_b)
        click.echo("     分析完成。")

        # 5. 生成报告
        click.echo("  -> 步骤4/4: 生成报告...")
        reporter = ReportGenerator(comparison_data, output_dir)
        report_paths = reporter.generate_all()
        click.echo("     报告生成成功:")
        for path in report_paths:
            click.echo(f"       - {path}")
        
        click.secho("✅ 全部完成！", fg='green')

    except Exception as e:
        click.secho(f"❌ 任务执行失败: {e}", fg='red', err=True)
        # 可以在这里添加更详细的错误日志记录
        # import traceback
        # traceback.print_exc()

@cli.command()
@click.argument('result_a', type=click.Path(exists=True))
@click.argument('result_b', type=click.Path(exists=True))
@click.option('--output-dir', default='./perf_results', help='报告输出目录。')
def analyze(result_a, result_b, output_dir):
    """
    独立分析两个已有的LKP结果目录，并生成报告。
    """
    click.secho(f"🔬 开始离线分析任务...", fg='cyan')
    os.makedirs(output_dir, exist_ok=True)
    
    try:
        click.echo("  -> 步骤1/2: 对比分析结果...")
        analyzer = AnalysisEngine()
        comparison_data = analyzer.analyze_lkp_results(result_a, result_b)
        click.echo("     分析完成。")

        click.echo("  -> 步骤2/2: 生成报告...")
        reporter = ReportGenerator(comparison_data, output_dir)
        report_paths = reporter.generate_all()
        click.echo("     报告生成成功:")
        for path in report_paths:
            click.echo(f"       - {path}")

        click.secho("✅ 分析完成！", fg='green')
    except Exception as e:
        click.secho(f"❌ 分析失败: {e}", fg='red', err=True)

if __name__ == '__main__':
    cli()
